<template>
  <PageCard title="AES 加解密">
    <n-space vertical size="large">
      <!-- 操作选择 -->
      <n-radio-group v-model:value="operation" size="large">
        <n-space>
          <n-radio-button value="encrypt">加密</n-radio-button>
          <n-radio-button value="decrypt">解密</n-radio-button>
        </n-space>
      </n-radio-group>

      <!-- 加密模式选择 -->
      <n-grid :cols="24" :x-gap="16">
        <n-grid-item :span="8">
          <n-form-item label="加密模式">
            <n-select v-model:value="mode" :options="modeOptions" />
          </n-form-item>
        </n-grid-item>
        <n-grid-item :span="8">
          <n-form-item label="填充方式">
            <n-select v-model:value="padding" :options="paddingOptions" />
          </n-form-item>
        </n-grid-item>
        <n-grid-item :span="8">
          <n-form-item label="密钥长度">
            <n-select v-model:value="keyLength" :options="keyLengthOptions" @update:value="generateKey" />
          </n-form-item>
        </n-grid-item>
      </n-grid>

      <!-- 密钥输入 -->
      <n-form-item label="密钥（Key）">
        <n-input-group>
          <n-input 
            v-model:value="key" 
            placeholder="请输入密钥（16/24/32字节）"
            :maxlength="32"
            show-count
          />
          <n-button type="primary" @click="generateKey">
            <template #icon>
              <n-icon :component="RefreshIcon" />
            </template>
            生成密钥
          </n-button>
        </n-input-group>
      </n-form-item>

      <!-- IV输入（CBC模式） -->
      <n-form-item v-if="mode === 'CBC'" label="偏移量（IV）">
        <n-input-group>
          <n-input 
            v-model:value="iv" 
            placeholder="请输入16字节的偏移量"
            :maxlength="16"
            show-count
          />
          <n-button type="primary" @click="generateIV">
            <template #icon>
              <n-icon :component="RefreshIcon" />
            </template>
            生成IV
          </n-button>
        </n-input-group>
      </n-form-item>

      <!-- 输入输出区域 -->
      <n-grid :cols="24" :x-gap="16">
        <n-grid-item :span="11">
          <n-h3 class="text-center">{{ operation === 'encrypt' ? '明文' : '密文' }}</n-h3>
          <n-input
            v-model:value="inputValue"
            type="textarea"
            :placeholder="operation === 'encrypt' ? '请输入要加密的明文' : '请输入要解密的密文（Base64格式）'"
            :rows="10"
          />
        </n-grid-item>
        <n-grid-item :span="2" class="flex items-center justify-center">
          <n-button 
            type="primary" 
            size="large"
            @click="processData"
            :loading="loading"
            :disabled="!canProcess"
          >
            <template #icon>
              <n-icon :component="operation === 'encrypt' ? LockIcon : UnlockIcon" />
            </template>
            {{ operation === 'encrypt' ? '加密' : '解密' }}
          </n-button>
        </n-grid-item>
        <n-grid-item :span="11">
          <n-h3 class="text-center">{{ operation === 'encrypt' ? '密文' : '明文' }}</n-h3>
          <n-input
            v-model:value="outputValue"
            type="textarea"
            :placeholder="operation === 'encrypt' ? '加密后的密文将显示在这里' : '解密后的明文将显示在这里'"
            :rows="10"
            readonly
          />
        </n-grid-item>
      </n-grid>

      <!-- 操作按钮 -->
      <n-space justify="end">
        <n-button @click="handleClear">
          <template #icon>
            <n-icon :component="ClearIcon" />
          </template>
          清空内容
        </n-button>
        <n-button type="primary" @click="handleCopy" :disabled="!outputValue">
          <template #icon>
            <n-icon :component="CopyIcon" />
          </template>
          复制结果
        </n-button>
      </n-space>
    </n-space>
    <n-divider />
    <UsageGuide
      :title="usageGuideConfig.title"
      :steps="usageGuideConfig.steps"
      :tips="usageGuideConfig.tips"
    />
  </PageCard>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { useMessage, NIcon, NAlert, NOl, NLi } from 'naive-ui';
import {
  LockClosedOutline as LockIcon,
  LockOpenOutline as UnlockIcon,
  RefreshOutline as RefreshIcon
} from '@vicons/ionicons5';
import { CopyAllOutlined as CopyIcon, ClearOutlined as ClearIcon } from '@vicons/material';
import PageCard from "@/components/PageCard.vue";
import UsageGuide from "@/components/UsageGuide.vue";
import { CryptoApi } from '@/api/crypto';

const message = useMessage();

// 状态管理
const operation = ref<'encrypt' | 'decrypt'>('encrypt');
const mode = ref<'ECB' | 'CBC'>('ECB');
const padding = ref('PKCS5Padding');
const keyLength = ref(16);
const key = ref('');
const iv = ref('');
const inputValue = ref('');
const outputValue = ref('');
const loading = ref(false);

// UsageGuide configuration
const usageGuideConfig = {
  title: '使用说明',
  steps: [
    '选择操作类型：加密或解密',
    '选择加密模式（ECB/CBC）和填充方式',
    '输入或生成密钥（支持128/192/256位）',
    'CBC模式需要额外输入或生成IV偏移量',
    '输入要处理的文本，点击执行按钮'
  ],
  tips: [
    'AES是一种对称加密算法，加解密使用相同的密钥',
    '密钥长度决定了加密强度：128位（16字节）、192位（24字节）、256位（32字节）',
    'CBC模式比ECB模式更安全，但需要额外的IV参数',
    '加密结果以Base64格式输出，便于存储和传输'
  ]
};

// 选项配置
const modeOptions = [
  { label: 'ECB', value: 'ECB' },
  { label: 'CBC', value: 'CBC' }
];

const paddingOptions = [
  { label: 'PKCS5Padding', value: 'PKCS5Padding' }
];

const keyLengthOptions = [
  { label: 'AES-128 (16字节)', value: 16 },
  { label: 'AES-192 (24字节)', value: 24 },
  { label: 'AES-256 (32字节)', value: 32 }
];

// 计算属性
const canProcess = computed(() => {
  if (!inputValue.value || !key.value) return false;
  if (mode.value === 'CBC' && !iv.value) return false;
  return true;
});

// 生成随机密钥
const generateKey = () => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  for (let i = 0; i < keyLength.value; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  key.value = result;
  message.success(`已生成${keyLength.value}字节密钥`);
};

// 生成随机IV
const generateIV = () => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  for (let i = 0; i < 16; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  iv.value = result;
  message.success('已生成16字节IV');
};

// 处理加解密
const processData = async () => {
  if (!canProcess.value) {
    message.warning('请填写所有必要参数');
    return;
  }

  loading.value = true;
  try {
    const params = {
      content: inputValue.value,
      key: key.value,
      operation: operation.value,
      mode: mode.value,
      padding: padding.value,
      ...(mode.value === 'CBC' ? { iv: iv.value } : {})
    };

    const response = await CryptoApi.aesProcess(params);
    
    if (response.code === 200) {
      outputValue.value = response.data;
      message.success(`${operation.value === 'encrypt' ? '加密' : '解密'}成功`);
    } else {
      message.error(response.message || '操作失败');
    }
  } catch (error: any) {
    message.error(error.message || '网络错误，请检查服务是否正常');
  } finally {
    loading.value = false;
  }
};

// 清空内容
const handleClear = () => {
  inputValue.value = '';
  outputValue.value = '';
};

// 复制结果
const handleCopy = async () => {
  if (!outputValue.value) return;
  try {
    await navigator.clipboard.writeText(outputValue.value);
    message.success('结果已成功复制到剪贴板！');
  } catch (err) {
    message.error('复制失败，请手动复制');
  }
};
</script>

<style scoped>
.text-center {
  text-align: center;
  margin: 0 0 16px 0;
}
</style>

